// Project adapted from https://developer.nvidia.com/blog/even-easier-introduction-cuda/
// 如何测量程序执行时间？

#include <stdio.h>
#include <math.h>
#include <chrono>  
// 使用std::chrono::high_resolution_clock来测量执行时间
// https://www.geeksforgeeks.org/measure-execution-time-function-cpp/
// 只在linux上运行的话，可以用<sys/time.h>中的gettimeofday()

// function to add the elements of two arrays
void vector_add(int array_size, float *x, float *y, float *z)
{
    for (int i = 0; i < array_size; i++)
        z[i] = x[i] + y[i];
}

int main(void)
{
    int array_size = 1<<20; // 1 M elements
    float *x, *y, *z;
    x = (float*)malloc(array_size*sizeof(float));
    y = (float*)malloc(array_size*sizeof(float));
    z = (float*)malloc(array_size*sizeof(float));

    // initialize x and y arrays on the host
    for (int i = 0; i < array_size; i++) {
        x[i] = 1.0f;
        y[i] = 2.0f;
    }
    // Get starting timepoint
    auto start = std::chrono::high_resolution_clock::now();
    vector_add(array_size, x, y, z);
     // Get ending timepoint
    auto stop = std::chrono::high_resolution_clock::now();
    //  stop - start得到执行时间
    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
    printf("Execution time: %ld us.\n", duration.count());

    // Check for errors (all values should be 3.0f)
    float maxError = 0.0f;
    for (int i = 0; i < array_size; i++)
        maxError = fmax(maxError, fabs(z[i]-3.0f));
    printf("Max Error: %f\n", maxError);

    // Free memory
    free(x);
    free(y);
    free(z);
    return 0;
}